package com.lsh.oms.core.proxy.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
import com.lsh.oms.core.model.http.HttpMessage;
import com.lsh.oms.core.model.order.*;
import com.lsh.oms.core.proxy.model.OrderSplitRequest;
import com.lsh.oms.core.service.asynservice.IEventListener;
import com.lsh.oms.core.utils.HttpUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author panxudong
 * @date 16/12/26
 */
@Component
public class MisProxy extends BaseProxy implements IEventListener {

    private static final Logger log = LoggerFactory.getLogger(MisProxy.class);

    private static final String GET_FROZEN_GOODS_PROVIDER_INFO_URL = "/market/info/getprovider";

    private static final String NOTIFY_RO_DETAIL_URL = "/order/afs/receiptCallback";

    private static final String NOTIFY_RO_URL = "/order/afs/arrivalCallback";

    private static final String NOTIFY_RO_FINISH_URL = "/order/afs/returnPassCallback";

    private static final String NOTIFY_RECEIPT_2_ACCOUT = "/order/info/arriveinform";

    private static final String RECEIPT_URL = "/order/receipt/done";

    private static final String ORDER_SPLIT_URL = "/order/info/createChildOrder";

    private static final String ORDER_PROVIDER_NAME = "/goods/provider/getInfo";

    private static final String ORDER_FINISH_NOTIFY = "/order/info/finalInform";

    private static final String PAY_ORDER_FREIGHT = "/order/info/paySuccess";

    private static final String SUPPLIER_GROUP = "/user/info/getPerformGroupId";

    @Value("${mis.host}")
    private String misHost;

    @Value("${market.host}")
    private String marketHost;

//    /**
//     * @param uuid
//     * @param lat
//     * @param lng
//     * @return
//     * @throws IOException
//     */
//    public FrozenGoodsProviderInfo getFrozenGoodsProviderInfo(String uuid, String lat, String lng) throws IOException {
//        StringBuilder url = new StringBuilder();
//        url.append(misHost).append(GET_FROZEN_GOODS_PROVIDER_INFO_URL).append("?lat=").append(lat).append("&lng=").append(lng);
//
//        Header[] headers = new Header[]{};
//
//        String message = "[MisProxy][Get frozen goods provider info][" + uuid + "]";
//
//        HttpMessage httpMessage = super.sendGetRequest(message, headers, url.toString());
//
//        if (!BaseProxy.isSuccess(httpMessage.getMessage())) {
//            throw new BusinessException("获取冻品供应商信息失败");
//        }
//
//        return new FrozenGoodsProviderInfo(BaseProxy.getContent(httpMessage.getMessage()));
//    }

    public String getSupplierGroup(Long uid, Long venderId){
        try {
            StringBuilder url = new StringBuilder();
            url.append(marketHost).append(SUPPLIER_GROUP).append("?uid=").append(uid);
            log.info(url.toString());
            Header[] headers = this.buildHeaders(venderId);

            String message = "[MisProxy][SUPPLIER_GROUP uid ][" + uid + "]";
            log.info(message);
            HttpMessage httpMessage = super.sendGetRequest(message, headers, url.toString());
            if (StringUtils.isBlank(httpMessage.getMessage())) {
                return "";
            }

            JSONObject messageJsonVo = JSON.parseObject(httpMessage.getMessage());
            if (messageJsonVo.getInteger("ret") == 0) {
                JSONArray content = messageJsonVo.getJSONArray("content");
                if(content != null && content.size() > 0){

                }
               return content.getInteger(0) + "";
            } else {
                return "";
            }
        } catch (IOException e) {
            log.error("获取履约用户组异常",e);
        }

        return "";

    }


    /**
     * @param asfId
     * @return
     * @throws IOException
     */
    public HttpMessage notifyRo(String asfId, Long venderId) throws IOException {

        StringBuilder url = new StringBuilder();
        url.append(misHost).append(NOTIFY_RO_URL).append("?afs_id=").append(asfId);
        log.info(url.toString());
        Header[] headers = this.buildHeaders(venderId);

        String message = "[MisProxy][notifyRo asfId ][" + asfId + "]";
        log.info(message);
        HttpMessage httpMessage = super.sendGetRequest(message, headers, url.toString());

        return httpMessage;
    }

    /**
     * @param asfId
     * @return
     * @throws IOException
     */
    public HttpMessage notifyFinishRo(String asfId, Long venderId) throws IOException {

        StringBuilder url = new StringBuilder();
        url.append(misHost).append(NOTIFY_RO_FINISH_URL).append("?afs_id=").append(asfId);
        log.info(url.toString());
        Header[] headers = this.buildHeaders(venderId);

        String message = "[MisProxy][notifyFinishRo asfId ][" + asfId + "]";
        log.info(message);
        HttpMessage httpMessage = super.sendGetRequest(message, headers, url.toString());

        return httpMessage;
    }

    /**
     * @param orderId
     * @return
     * @throws IOException
     */
    public HttpMessage notifyReceipt2Account(Long orderId, Long venderId) throws IOException {

        StringBuilder url = new StringBuilder();
        url.append(misHost).append(NOTIFY_RECEIPT_2_ACCOUT).append("?order_id=").append(orderId);
        log.info(url.toString());
        Header[] headers = this.buildHeaders(venderId);

        String message = "[MisProxy][notifyReceipt2Account orderId:" + orderId + "]";
        log.info(message);
        HttpMessage httpMessage = super.sendGetRequest(message, headers, url.toString());

        return httpMessage;
    }

    /**
     * @param afsId
     * @param orderRoHead
     * @param osh
     * @param osds
     * @return
     * @throws IOException
     */
    public JSONObject notifyDetailRo(String afsId, OrderRoHead orderRoHead, OrderShippingHeadWithBLOBs osh, List<OrderShippingDetail> osds, Long venderId) throws IOException {

        StringBuilder url = new StringBuilder(misHost).append(NOTIFY_RO_DETAIL_URL);
        log.info(url.toString());

        JSONArray skuList = new JSONArray();
        List<OrderRoDetail> details = orderRoHead.getDetails();
        for (OrderRoDetail detail : details) {
            JSONObject item = new JSONObject(4);
            item.put("sku_id", detail.getSkuId());
            item.put("qty", detail.getQty());

            skuList.add(item);
        }

        JSONArray shippingInfoDetailList = new JSONArray(osds.size());
        for (OrderShippingDetail osd : osds) {
            JSONObject item = JSON.parseObject(osd.getExt());
//            item.put("item_code", osd.getItemCode());
            item.put("sku_id", osd.getSkuId().toString());
            item.put("sku_name", osd.getSkuName());
            item.put("sale_unit", osd.getSaleUnit().toString());
            item.put("real_qty", osd.getRealQty());
            item.put("qty", osd.getQty());
            item.put("price", osd.getPrice().toString());
            item.put("money", osd.getMoney().toString());

            shippingInfoDetailList.add(item);
        }
        JSONObject shipExt = JSON.parseObject(osh.getExt());
//        log.info("shipExt ext " + shipExt.toJSONString());
        JSONObject extHeadInfo = shipExt.getJSONObject("head_info");
//        log.info("shipExt ext head_info " + extHeadInfo.toJSONString());
        JSONObject shippingInfoParams = new JSONObject();

        shippingInfoParams.put("head_info", extHeadInfo);
        shippingInfoParams.put("detail_list", shippingInfoDetailList);

        List<BasicNameValuePair> pairs = new ArrayList<>(4);
        pairs.add(new BasicNameValuePair("afs_id", afsId));
        pairs.add(new BasicNameValuePair("order_id", osh.getOrderId().toString()));
        pairs.add(new BasicNameValuePair("sku_list", skuList.toJSONString()));
        pairs.add(new BasicNameValuePair("shipping_info", shippingInfoParams.toJSONString()));
        HttpEntity entity = new UrlEncodedFormEntity(pairs, Consts.UTF_8);

//        log.info("notifyDetailRo 服务参数shipping_info:" + shippingInfoParams.toJSONString());
//        log.info("notifyDetailRo 服务参数sku_list:" + skuList.toJSONString());
        String result = HttpUtils.post(url.toString(), entity, false, buildHeaders(venderId)).getData();
        log.info("notifyDetailRo 服务返回:" + result);
        // getJSONObject("content");
        JSONObject content = JSON.parseObject(result);

        return content;
    }

    @Subscribe
    @AllowConcurrentEvents
    public void receiptDone(ReceiptOrderDone receiptOrderDone) {

        StringBuilder url = new StringBuilder(misHost).append(RECEIPT_URL);
        log.info(url.toString());
        List<BasicNameValuePair> pairList = new ArrayList<>(4);
        pairList.add(new BasicNameValuePair("order_id", String.valueOf(receiptOrderDone.getOrderId())));
        pairList.add(new BasicNameValuePair("receipt_order_id", receiptOrderDone.getReceiptOrderId().toString()));
        pairList.add(new BasicNameValuePair("shipping_order_id", receiptOrderDone.getShippingOrderId().toString()));
        pairList.add(new BasicNameValuePair("money", receiptOrderDone.getMoney().toString()));
        pairList.add(new BasicNameValuePair("uid", receiptOrderDone.getUid().toString()));
        pairList.add(new BasicNameValuePair("receipt_at", receiptOrderDone.getReceiptAt().toString()));
        pairList.add(new BasicNameValuePair("arrived_at", receiptOrderDone.getArrivedAt().toString()));
        pairList.add(new BasicNameValuePair("zone_id", receiptOrderDone.getZoneId().toString()));
        pairList.add(new BasicNameValuePair("address_id", receiptOrderDone.getAddressId().toString()));
        pairList.add(new BasicNameValuePair("pay_type", receiptOrderDone.getPayType().toString()));
        log.info(receiptOrderDone.getOrderId() + "签收通知mis 请求参数 {}", JSON.toJSONString(pairList));
        HttpEntity entity = new UrlEncodedFormEntity(pairList, Consts.UTF_8);

        String result = HttpUtils.post(url.toString(), entity, false, this.buildHeaders(receiptOrderDone.getVenderId())).getData();
        log.info(receiptOrderDone.getOrderId() + "服务返回:" + result);
        JSONObject content = JSON.parseObject(result).getJSONObject("content");
        log.info(receiptOrderDone.getOrderId() + "签收通知mis 返回结果 {}", JSON.toJSONString(content));

    }

    /**
     * 拆单处理
     *
     * @param orderSplitRequest 拆单参数
     * @return 拆单结果
     */
    public JSONObject splitPush(OrderSplitRequest orderSplitRequest, Long venderId) {

        Long orderCode = orderSplitRequest.getOrderId();
        StringBuilder url = new StringBuilder(marketHost).append(ORDER_SPLIT_URL);
        log.info(url.toString());
        List<BasicNameValuePair> pairList = new ArrayList<>(4);
        pairList.add(new BasicNameValuePair("order_id", String.valueOf(orderCode)));
        pairList.add(new BasicNameValuePair("split_items", JSON.toJSONString(orderSplitRequest.getSplitItems())));

        log.info(orderCode + " 请求计算服务拆单 请求参数 {}", JSON.toJSONString(pairList));
        HttpEntity entity = new UrlEncodedFormEntity(pairList, Consts.UTF_8);

        String result = HttpUtils.post(url.toString(), entity, false, this.buildHeaders(venderId)).getData();
        log.info(orderCode + " 请求计算服务拆单 服务返回:{}", result);
        JSONObject content = JSON.parseObject(result).getJSONObject("content");
        log.info(orderCode + " 请求计算服务拆单 返回结果 {}", JSON.toJSONString(content));

        return content;
    }

    public JSONObject payFreight(Long orderCode, Long venderId) {

        StringBuilder url = new StringBuilder(misHost).append(PAY_ORDER_FREIGHT);
        log.info(url.toString());
        List<BasicNameValuePair> pairList = new ArrayList<>(4);
        pairList.add(new BasicNameValuePair("order_id", String.valueOf(orderCode)));

        log.info(orderCode + " 通知商城订单支付 {}", JSON.toJSONString(pairList));
        HttpEntity entity = new UrlEncodedFormEntity(pairList, Consts.UTF_8);

        String result = HttpUtils.post(url.toString(), entity, false, this.buildHeaders(venderId)).getData();
        log.info(orderCode + " 通知商城订单支付 服务返回:{}", result);
        JSONObject content = JSON.parseObject(result).getJSONObject("content");
        log.info(orderCode + " 通知商城订单支付 返回结果 {}", JSON.toJSONString(content));

        return content;
    }

    public String requestProviderName(String providerId, Long venderId) {

        if ("0".equals(providerId)) {
            return "自营";
        }

        String providerName = "";
        JSONObject content = this.requestProviderInfo(providerId, venderId);

        if (null != content) {
            providerName = content.getString("provider_name");
        }

        return providerName;
    }

    private JSONObject requestProviderInfo(String providerId, Long venderId) {

        StringBuilder url = new StringBuilder(marketHost).append(ORDER_PROVIDER_NAME).append("?provider_id=").append(providerId);

        log.info(providerId + " 请求mis获取供商名称 请求参数 {}", url);
        Header[] headers = this.buildHeaders(venderId);

        try {
            HttpMessage httpMessage = HttpUtils.sendGetRequest(url.toString(), headers);

            log.info(providerId + " 请求mis获取供商名称 服务返回 httpMessage:{}", JSON.toJSONString(httpMessage));
            String result = null;
            if (httpMessage.getStatus().equals("200")) {
                result = httpMessage.getMessage();
            }

            log.info(providerId + " 请求mis获取供商名称 服务返回:{}", result);
            if (result == null) {
                return null;
            }

            return JSON.parseObject(result).getJSONObject("content");
        } catch (IOException e) {
            log.error("获取供商名称异常", e);
        }

        return null;
    }

    public String requestProviderPhone(String providerId, Long venderId) {

        if ("0".equals(providerId)) {
            return "";
        }

        String providerPhone = "";
        JSONObject content = this.requestProviderInfo(providerId, venderId);


        if (null != content) {
            providerPhone = content.getString("provider_phone");
        }

        return providerPhone;
    }

    public JSONObject orderFinishNotify(Long orderCode, Long venderId) {

        StringBuilder url = new StringBuilder(misHost).append(ORDER_FINISH_NOTIFY);
        log.info(url.toString());
        List<BasicNameValuePair> pairList = new ArrayList<>(4);
        pairList.add(new BasicNameValuePair("order_id", String.valueOf(orderCode)));

        log.info(orderCode + " 通知商城订单完成 请求参数 {}", JSON.toJSONString(pairList));
        HttpEntity entity = new UrlEncodedFormEntity(pairList, Consts.UTF_8);

        String result = HttpUtils.post(url.toString(), entity, false, this.buildHeaders(venderId)).getData();
        log.info(orderCode + " 通知商城订单完成 服务返回:{}", result);
        JSONObject resultJson = JSON.parseObject(result);
        log.info(orderCode + " 通知商城订单完成 返回结果 {}", resultJson.toJSONString());

        return resultJson;
    }


    private Header[] buildHeaders(Long venderId) {
        Header[] headers = {new BasicHeader("api-version", "1.1"),
                new BasicHeader("platform", "oms"),
                new BasicHeader("venderId", venderId + ""),
                new BasicHeader("sign", "md5")};
        return headers;
    }


    public static class FrozenGoodsProviderInfo {

        private String providerId;

        FrozenGoodsProviderInfo() {

        }

        FrozenGoodsProviderInfo(String providerString) {
            JSONObject providerObject = JSONObject.parseObject(providerString);
            if (providerObject.containsKey("provider_id")) {
                this.providerId = providerObject.getString("provider_id");
            } else {
                this.providerId = null;
            }
        }

        public String getProviderId() {
            return providerId;
        }

        public void setProviderId(String providerId) {
            this.providerId = providerId;
        }
    }

}
